package com.xm.singleton;

/**
 * 双重检查锁（Double-Checked Locking）
 *  volatile 关键字防止指令重排序
 *  实例化对象的过程：
 *      1、分配内存空间
 *      2、初始化对象
 *      3、将引用指向内存地址
 *  问题：
 *      JVM 可能进行指令重排序（步骤 2 和 3 交换）。
 *      若线程 A 执行到步骤 3（未完成初始化），
 *      线程 B 可能通过第一次检查（instance != null）得到一个未初始化的对象。
 *  解决方案：
 *      使用 volatile 修饰 instance，
 *      禁止 JVM 的指令重排序，
 *      确保对象完全初始化后，
 *      引用才被赋值。
 */
public class DDoubleChecked {
    //volatile 禁止指令重排序，确保可见性
    private static volatile DDoubleChecked instance;
    private DDoubleChecked() {}

    public static DDoubleChecked getInstance() {
        if (instance == null) {
            synchronized (DDoubleChecked.class) {
                if (instance == null) {
                    instance = new DDoubleChecked();
                }
            }
        }
        return instance;
    }
}
